﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using YJKRevitDimensionText.VerticalAutoDim.ProgressBar;

namespace YJKRevitDimensionText.VerticalAutoDim.OutWallSearch
{
	internal class OutWallSearcherManager : IDisposable
	{
		private IDictionary<ElementId, IList<OutWallData>> Level2OutWallData
		{
			get
			{
				return this.OutWallCreator.LevelId2OutWallData;
			}
		}

		public IList<Element> ArrayParapetWall { get; private set; }

		public IList<OutWallData> ArrayOutWallByViewDirection
		{
			get
			{
				List<OutWallData> lstOutWallData = new List<OutWallData>();
				EnumerableExternsion.ForEach<IList<OutWallData>>(this.Level2OutWallData.Values, delegate(IList<OutWallData> lstData)
				{
					lstOutWallData.AddRange(lstData);
				});
				return lstOutWallData.Distinct(new OutWallDataEqualityComparer()).ToList<OutWallData>();
			}
		}

		public OutWallSearcherManager(Autodesk.Revit.ApplicationServices.Application app, Autodesk.Revit.DB.Document doc, IOutWallCreator outWallCreator, IDualStatusProgressBarProcess dualStatusProgressBarProcess)
		{
			this.Application = app;
			this.Doc = doc;
			this.OutWallCreator = outWallCreator;
			this.DualStatusProgressBarProcess = dualStatusProgressBarProcess;
			this.Application.FailuresProcessing += this.OnFailuresProcessing;
			this.TransactionGroup = new TransactionGroup(this.Doc, "TempOutWallFilterTransactionGroup");
		}

		public void Dispose()
		{
            if ((int)this.TransactionGroup.GetStatus() == 1)
			{
				this.TransactionGroup.RollBack();
			}
		}

		public bool InitOutWallSearch()
		{
			if (this.OutWallCreator.IsParapetWall != null)
			{
				FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.Doc);
				this.ArrayParapetWall = filteredElementCollector.OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().Where(this.OutWallCreator.IsParapetWall).ToList<Element>();
			}
			this.TransactionGroup.Start();
			if (this.ArrayParapetWall.Count > 0)
			{
				Transaction transaction = new Transaction(this.Doc, "TempDelParapetWalls");
				try
				{
					transaction.Start();
					List<ElementId> list = (from e in this.ArrayParapetWall
					select e.Id).ToList<ElementId>();
					this.Doc.Delete(list);
					transaction.Commit();
				}
				catch
				{
					if ((int)transaction.GetStatus() == 1)
					{
						transaction.RollBack();
						return false;
					}
				}
			}
			this.OutWallCreator.OutWallSearcher();
			return true;
		}

		private void OnFailuresProcessing(object sender, FailuresProcessingEventArgs e)
		{
			FailuresAccessor failuresAccessor = e.GetFailuresAccessor();
			string transactionName = failuresAccessor.GetTransactionName();
			IList<FailureMessageAccessor> failureMessages = failuresAccessor.GetFailureMessages();
			if (failureMessages.Count == 0)
			{
				e.SetProcessingResult((FailureProcessingResult)0);
				return;
			}
			if (transactionName.Equals("createNewRoomBoundaryLines"))
			{
				foreach (FailureMessageAccessor failureMessageAccessor in failureMessages)
				{
					if ((int)failureMessageAccessor.GetSeverity() == 2)
					{
						failuresAccessor.ResolveFailure(failureMessageAccessor);
					}
					else if ((int)failureMessageAccessor.GetSeverity() == 1)
					{
						failuresAccessor.DeleteWarning(failureMessageAccessor);
					}
				}
				e.SetProcessingResult((FailureProcessingResult)1);
				return;
			}
			e.SetProcessingResult((FailureProcessingResult)0);
		}

		private readonly IOutWallCreator OutWallCreator;

		private readonly IDualStatusProgressBarProcess DualStatusProgressBarProcess;

		private readonly Application Application;

		private readonly Document Doc;

		private readonly TransactionGroup TransactionGroup;
	}
}
